#include "bsp_system_clock.h"
#include "string.h"
#include "stdio.h"

static volatile uint32_t core_ms = 0;
static volatile uint32_t core_s = 0;
static volatile uint32_t core_delay_ms = 0;

/*******************************************************************************
* 函数功能 : 系统时钟初始化
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
void bsp_system_clock_config(void){
	//先使用内部时钟
	rcu_system_clock_source_config(RCU_CKSYSSRC_IRC16M);
	rcu_deinit();
	//开始打开外部高速时钟
	rcu_osci_on(RCU_HXTAL);
	if(rcu_osci_stab_wait(RCU_HXTAL) != SUCCESS){//等待时钟打开并稳定
		while(1){;}
	}
	//配置各个总线时钟分频系数，具体的根据应用手册中的来设置（每个总线有最大允许的时钟频率）
	rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1);
	rcu_apb1_clock_config(RCU_APB1_CKAHB_DIV4);
	rcu_apb2_clock_config(RCU_APB2_CKAHB_DIV2);
	rcu_pll_config(RCU_PLLSRC_HXTAL,25,480,2,10);//倍频系数设置
	rcu_osci_on(RCU_PLL_CK);//打开PLL时钟功能
	if(rcu_osci_stab_wait(RCU_PLL_CK) != SUCCESS){//等待时钟稳定
		while(1){;}
	}
	rcu_system_clock_source_config(RCU_CKSYSSRC_PLLP);//配置内核时钟源为PLL倍频出来的
	while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){
		;
	}
	//获取配置好的个各个总线时钟值，可不用
	rcu_clock_freq_get(CK_SYS);
	rcu_clock_freq_get(CK_AHB);
	rcu_clock_freq_get(CK_APB1);
	rcu_clock_freq_get(CK_APB2);
	//配置系统中断为1Khz
	SysTick_Config(SystemCoreClock/1000);
	//使能系统中断
	NVIC_SetPriority(SysTick_IRQn, 0x00U);

	//打开SWD接口的IO引脚对应的外设时钟
	rcu_periph_clock_enable(RCU_GPIOA);
	rcu_periph_clock_enable(RCU_GPIOH);
}
/*******************************************************************************
* 函数功能 : 系统时间戳刷新
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
void Core_Run_Time_Update(void){
	core_ms++;
	if(core_ms == 1000){
		core_ms = 0;
		core_s++;
	}
	core_delay_ms++;
}
/*******************************************************************************
* 函数功能 : 微秒级延时
* 输    入 : 要延时的微秒（小于1000）
* 输    出 : 无
*******************************************************************************/
void delay_us(uint32_t us){
	uint32_t ticks;
	uint32_t told, tnow, tcnt = 0;
	uint32_t reload = SysTick->LOAD;

	ticks = us * reload / (1000000 / 1000);
	told = SysTick->VAL;
	while (1)
	{
		tnow = SysTick->VAL;
		if (tnow != told){
			if (tnow < told){
				tcnt += told - tnow;
			}
			else{
				tcnt += reload - tnow + told;
			}
			told = tnow;
			if (tcnt >= ticks){
				break;
			}
		}
	}
}
/*******************************************************************************
* 函数功能 : 毫秒级延时
* 输    入 : 要延时的毫秒数
* 输    出 : 无
*******************************************************************************/
void delay_ms(uint32_t ms){
	core_delay_ms = 0;
	while(core_delay_ms < ms){};
}
/*******************************************************************************
* 函数功能 : 获取系统时钟毫秒时间戳
* 输    入 : 无
* 输    出 : 毫秒时间戳
*******************************************************************************/
unsigned int Get_Core_Run_Time_Ms(void){
	return (unsigned int)core_ms;
}
/*******************************************************************************
* 函数功能 : 系统时钟运行的时间，单位秒
* 输    入 : 无
* 输    出 : 系统运行的时间秒数
*******************************************************************************/
unsigned int Get_Core_Run_Time_S(void){
	return (unsigned int)core_s;
}
char Core_Run_Time_Str[128] = {0};
/*******************************************************************************
* 函数功能 : 系统时间戳字符串
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
const char *Get_Core_Run_Time_Str(void){
	memset((char *)Core_Run_Time_Str,0,sizeof(Core_Run_Time_Str));
	sprintf((char *)Core_Run_Time_Str,"%05d-%02d-%02d-%02d:%03d",Get_Core_Run_Time_S()/86400,(Get_Core_Run_Time_S()/3600)%24,(Get_Core_Run_Time_S()/60)%60,Get_Core_Run_Time_S()%60,Get_Core_Run_Time_Ms());
	return Core_Run_Time_Str;
}